﻿using Common.MinIo.Model;
using Common.Tools;
using Minio;
using Minio.DataModel.Args;
using Newtonsoft.Json;
using System.Data;
using System.Globalization;

namespace Common.MinIo
{
    /// <summary>
    /// minio文件访问操作
    /// </summary>
    public class MinIoObjectOperate : IStorageObjectOperate
    {
        /// <summary>
        /// Minio客户端
        /// </summary>
        private readonly IMinioClient _minioClient;
        /// <summary>
        /// Minio配置
        /// </summary>
        private readonly MinIoConfig _minIoConfig;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="config">Minio配置</param>
        public MinIoObjectOperate(MinIoConfig config)
        {
            _minIoConfig = config;
            _minioClient = new MinioClient().WithEndpoint(config.EndPoint).WithCredentials(config.AccessKey, config.SecretKey).WithTimeout(config.RequestTimeout).Build();
        }

        #region 方法 

        #region 获取存储地址
        /// <summary>
        /// 获取存储地址
        /// </summary>
        /// <returns></returns>
        public Task<string> GetStorageUrl()
        {
            return Task.FromResult($"http://{_minIoConfig.EndPoint}");
        }

        #endregion

        #region 上传对象

        /// <summary>
        /// 上传对象
        /// </summary>
        /// <param name="objectType">文件类型</param>
        /// <param name="objName">文件唯一Id</param>
        /// <param name="data">文件数据</param>
        /// <returns></returns>
        public async Task<bool> PutObjectAsync(StorageObjectTypeDefine objectType, string objName, Stream data)
        {
            if (string.IsNullOrEmpty(objName) || data.Length == 0)
            {
                LogHelper.Error($"上传对象参数错误");
                return false;
            }
            LogHelper.Info($"上传{objectType}文件，文件名：{objName}");
            var args = new PutObjectArgs().WithBucket(await GetBucketName(objectType)).WithObject(objName).WithStreamData(data).WithObjectSize(data.Length);
            return await PutObjectAsync(args);
        }
        /// <summary>
        /// 上传对象
        /// </summary>
        /// <param name="objectType">文件类型</param>
        /// <param name="objName">文件唯一Id</param>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        public async Task<bool> PutObjectAsync(StorageObjectTypeDefine objectType, string objName, string filePath)
        {
            if (string.IsNullOrEmpty(objName) || string.IsNullOrEmpty(filePath))
            {
                LogHelper.Error($"上传对象参数错误");
                return false;
            }
            LogHelper.Info($"上传{objectType}文件，文件名：{objName}");
            // 使用 using 语句确保文件流在使用后自动关闭
            using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                // 上传文件到 MinIO
                return await PutObjectAsync(objectType, objName, fileStream);
            }

        }
        /// <summary>
        /// 上传对象
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objName">文件唯一Id</param>
        /// <param name="data">文件数据</param>
        /// <returns></returns>
        public async Task<bool> PutObjectAsync(string bucketName, string objName, Stream data)
        {
            if (string.IsNullOrEmpty(bucketName) || string.IsNullOrEmpty(objName) || data.Length == 0)
            {
                LogHelper.Error($"上传对象参数错误");
                return false;
            }

            LogHelper.Info($"上传{bucketName}文件，文件名：{objName}");
            var args = new PutObjectArgs().WithBucket(await GetBucketName(bucketName)).WithObject(objName).WithStreamData(data).WithObjectSize(data.Length);
            return await PutObjectAsync(args);
        }

        /// <summary>
        /// 上传对象
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objName">文件唯一Id</param>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        public async Task<bool> PutObjectAsync(string bucketName, string objName, string filePath)
        {
            if (string.IsNullOrEmpty(bucketName) || string.IsNullOrEmpty(objName) || string.IsNullOrEmpty(filePath))
            {
                LogHelper.Error($"上传对象参数错误");
                return false;
            }

            LogHelper.Info($"上传{bucketName}文件，文件名：{objName}");
            // 使用 using 语句确保文件流在使用后自动关闭
            using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                // 上传文件到 MinIO
                return await PutObjectAsync(bucketName, objName, fileStream);
            }
        }
        /// <summary>
        /// 上传对象
        /// </summary>
        /// <param name="args">参数</param>
        /// <returns></returns>
        private async Task<bool> PutObjectAsync(PutObjectArgs args)
        {
            //失败重试三次
            for (int i = 1; i <= 3; i++)
            {
                try
                {
                    var result = await _minioClient.PutObjectAsync(args).ConfigureAwait(false);
                    if (result != null && !string.IsNullOrWhiteSpace(result.Etag))
                        return true;
                    LogHelper.Error($"上传对象失败：{JsonConvert.SerializeObject(result)}");
                    await Task.Delay(i * 1000);
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"上传对象异常{ex.Message}", ex);
                    await Task.Delay(i * 1000);
                }
            }
            return false;
        }
        #endregion

        #region 获取对象

        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="objectType">文件类型</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <param name="offset">是起始字节的位置</param>
        /// <param name="length">读取长度</param>
        /// <returns></returns>
        public async Task<Stream> GetObjectAsync(StorageObjectTypeDefine objectType, string objectName, long offset = 0, long length = 0)
        {
            try
            {
                if (string.IsNullOrEmpty(objectName))
                {
                    LogHelper.Error($"获取对象参数错误");
                    return null;
                }

                LogHelper.Info($"获取{objectType}文件，文件名：{objectName}");
                var result = new MemoryStream();
                var args = new GetObjectArgs().WithBucket(await GetBucketName(objectType)).WithObject(objectName).WithCallbackStream(stream =>
                {
                    stream.CopyTo(result);
                });
                if (length > 0)
                {
                    args.WithOffsetAndLength(offset, length);
                }
                var objectStat = await _minioClient.GetObjectAsync(args).ConfigureAwait(false);
                result.Seek(0, SeekOrigin.Begin);
                return result;
            }
            catch (Exception ex)
            {
                LogHelper.Error($"获取对象异常{ex.Message}", ex);
                return null;
            }

        }
        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <param name="offset">是起始字节的位置</param>
        /// <param name="length">读取长度</param>
        /// <returns></returns>
        public async Task<Stream> GetObjectAsync(string bucketName, string objectName, long offset = 0, long length = 0)
        {
            try
            {
                if (string.IsNullOrEmpty(bucketName) || string.IsNullOrEmpty(objectName))
                {
                    LogHelper.Error($"获取对象参数错误");
                    return null;
                }

                LogHelper.Info($"获取{bucketName}文件，文件名：{objectName}");
                var result = new MemoryStream();
                var args = new GetObjectArgs().WithBucket(await GetBucketName(bucketName)).WithObject(objectName).WithCallbackStream(stream =>
                {
                    stream.CopyTo(result);
                });
                if (length > 0)
                {
                    args.WithOffsetAndLength(offset, length);
                }
                var objectStat = await _minioClient.GetObjectAsync(args).ConfigureAwait(false);
                result.Seek(0, SeekOrigin.Begin);
                return result;
            }
            catch (Exception ex)
            {
                LogHelper.Error($"获取对象异常{ex.Message}", ex);
                return null;
            }
        }

        #endregion

        #region 获取文件大小
        /// <summary>
        /// 获取文件大小
        /// </summary>
        /// <param name="objectType">文件类型</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <returns></returns>
        public async Task<long> GetObjectSize(StorageObjectTypeDefine objectType, string objectName)
        {
            try
            {
                var statObjectArgs = new StatObjectArgs().WithBucket(await GetBucketName(objectType)).WithObject(objectName);
                var objectStat = await _minioClient.StatObjectAsync(statObjectArgs);
                return objectStat?.Size ?? 0;
            }
            catch (Exception ex)
            {
                LogHelper.Error($"获取文件大小异常{ex.Message}", ex);
                return 0;
            }

        }
        /// <summary>
        /// 获取文件大小
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <returns></returns>
        public async Task<long> GetObjectSize(string bucketName, string objectName)
        {
            try
            {
                var statObjectArgs = new StatObjectArgs().WithBucket(await GetBucketName(bucketName)).WithObject(objectName);
                var objectStat = await _minioClient.StatObjectAsync(statObjectArgs);
                return objectStat?.Size ?? 0;
            }
            catch (Exception ex)
            {
                LogHelper.Error($"获取文件大小异常{ex.Message}", ex);
                return 0;
            }

        }
        #endregion

        #region 删除对象

        /// <summary>
        /// 删除对象
        /// </summary>
        /// <param name="objectType">文件类型</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <returns></returns>
        public async Task RemoveObjectAsync(StorageObjectTypeDefine objectType, string objectName)
        {
            try
            {
                if (string.IsNullOrEmpty(objectName))
                {
                    LogHelper.Error("删除对象时，参数错误");
                    return;
                }
                var args = new RemoveObjectArgs().WithBucket(await GetBucketName(objectType)).WithObject(objectName);
                await _minioClient.RemoveObjectAsync(args).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LogHelper.Error($"删除对象异常{ex.Message}", ex);
            }

        }
        /// <summary>
        /// 删除对象
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <returns></returns>
        public async Task RemoveObjectAsync(string bucketName, string objectName)
        {
            try
            {
                if (string.IsNullOrEmpty(bucketName) || string.IsNullOrEmpty(objectName))
                {
                    LogHelper.Error("删除对象时，参数错误");
                    return;
                }
                var args = new RemoveObjectArgs().WithBucket(await GetBucketName(bucketName)).WithObject(objectName);
                await _minioClient.RemoveObjectAsync(args).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LogHelper.Error($"删除对象异常{ex.Message}", ex);
            }

        }
        /// <summary>
        /// 批量删除对象
        /// </summary>
        /// <param name="objectType">文件类型</param>
        /// <param name="objectNames">文件唯一Id</param> 
        /// <returns></returns>
        public async Task RemoveObjectAsync(StorageObjectTypeDefine objectType, IList<string> objectNames)
        {
            try
            {
                if (!objectNames.Any())
                {
                    LogHelper.Error("批量删除对象，参数错误");
                    return;
                }
                var args = new RemoveObjectsArgs().WithBucket(await GetBucketName(objectType)).WithObjects(objectNames);
                var result = await _minioClient.RemoveObjectsAsync(args).ConfigureAwait(false);
                foreach (var item in result)
                {
                    LogHelper.Info($"删除失败{item.BucketName},{item.DeleteMarker}");
                }

            }
            catch (Exception ex)
            {
                LogHelper.Error($"批量删除对象异常{ex.Message}", ex);
            }

        }
        /// <summary>
        /// 批量删除对象
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectNames">文件唯一Id</param> 
        /// <returns></returns>
        public async Task RemoveObjectAsync(string bucketName, IList<string> objectNames)
        {
            try
            {
                if (string.IsNullOrEmpty(bucketName) || !objectNames.Any())
                {
                    LogHelper.Error("批量删除对象，参数错误");
                    return;
                }
                var args = new RemoveObjectsArgs().WithBucket(await GetBucketName(bucketName)).WithObjects(objectNames);
                var result = await _minioClient.RemoveObjectsAsync(args).ConfigureAwait(false);
                foreach (var item in result)
                {
                    LogHelper.Info($"删除失败{item.BucketName},{item.DeleteMarker}");
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error($"批量删除对象异常{ex.Message}", ex);
            }
        }
        #endregion

        #region 查询存储桶文件 
        /// <summary>
        /// 查询存储桶文件
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="isRecursive">是否递归</param>
        /// <returns>返回当前目录下的文件或者文件夹</returns>
        public async Task<List<BucketFileInfo>> SearchObjectsAsync(string path, bool isRecursive = false)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(path))//如果文件路径为空，则查询所有存储桶
                {
                    var buckets = await _minioClient.ListBucketsAsync().ConfigureAwait(false);
                    var result = buckets?.Buckets?.Select(x => new BucketFileInfo
                    {
                        Name = x.Name,
                        Path = x.Name,
                    })?.ToList() ?? new List<BucketFileInfo>();
                    return result;
                }
                //如果文件路径不为空，则分割第一位为存储桶，后面为路径
                var pathStr = path.TrimStart('/').Split('/');
                var bucketName = pathStr[0];
                var prefix = string.Join("/", pathStr.Skip(1));
                //最后一位补/
                prefix = !string.IsNullOrWhiteSpace(prefix) ? (prefix.EndsWith('/') ? prefix : prefix + "/") : prefix;

                var args = new ListObjectsArgs().WithBucket(bucketName).WithPrefix(prefix).WithRecursive(isRecursive);
                var list = new List<BucketFileInfo>();
                await foreach (var item in _minioClient.ListObjectsEnumAsync(args).ConfigureAwait(false))
                {
                    //替换前面的路径并且去除最后一位/
                    list.Add(new BucketFileInfo
                    {
                        Key = item.Key,
                        Name = !string.IsNullOrWhiteSpace(prefix) ? item.Key.Replace(prefix, "").TrimEnd('/') : item.Key.TrimEnd('/'),
                        Path = $"{bucketName}/{item.Key.TrimEnd('/')}",
                        IsDir = item.IsDir,
                        Size = item.Size,
                        IsLatest = item.IsLatest
                    });
                }
                return list;
            }
            catch (Exception ex)
            {
                LogHelper.Error($"查询存储桶文件异常{ex.Message}", ex);
                return new List<BucketFileInfo>();
            }

        }

        #endregion

        #region 按条件删除文件

        /// <summary>
        /// 按条件删除文件
        /// </summary>
        /// <returns>返回当前目录下的文件或者文件夹</returns>
        public async Task<bool> DeleteObjectsByConditionAsync(DeleteParam param)
        {
            if (param == null) throw new ArgumentNullException(nameof(param));
            if (string.IsNullOrWhiteSpace(param.BucketName))
                throw new ArgumentNullException("存储桶不能为空");
            if (param.ObjectTypes.Count == 0)
                throw new ArgumentNullException("文件类型不能为空");
            try
            {
                var days = (param.EndTime.Date - param.StartTime.Date).Days;//获取相差的天数
                foreach (var objectType in param.ObjectTypes)
                {
                    for (int i = 0; i <= days; i++)
                    {
                        //例如：四川/音频/2024/7/7
                        var path = $"{param.BucketName}/{objectType.ToString().ToLower()}/{param.StartTime.Date.AddDays(i).ToString("yyyy/MM/dd", CultureInfo.InvariantCulture)}";
                        var list = await SearchObjectsAsync(path, true);
                        if (list.Count == 0) continue;
                        await RemoveObjectAsync(param.BucketName, list.Select(x => x.Key).ToList());
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                LogHelper.Error($"按条件删除文件异常{ex.Message}", ex);
                return false;
            }


        }

        #endregion

        #region 获取存储桶的大小

        /// <summary>
        /// 获取存储桶的大小
        /// </summary>
        /// <returns>返回当前目录下的文件或者文件夹</returns>
        public async Task<List<BucketSize>> GetBucketSizeAsync()
        {
            try
            {
                var buckets = await _minioClient.ListBucketsAsync().ConfigureAwait(false);
                var bucketNames = buckets?.Buckets?.Select(x => x.Name)?.ToList() ?? new List<string>();
                var result = new List<BucketSize>();
                foreach (var bucketName in bucketNames)
                {
                    var args = new ListObjectsArgs().WithBucket(bucketName).WithRecursive(true);
                    ulong size = 0;
                    await foreach (var item in _minioClient.ListObjectsEnumAsync(args).ConfigureAwait(false))
                    {
                        size += item.Size;
                    }
                    result.Add(new BucketSize { BucketName = bucketName, Size = size });
                }

                return result;
            }
            catch (Exception ex)
            {
                LogHelper.Error($"获取存储桶的大小异常{ex.Message}", ex);
                return new List<BucketSize>();
            }


        }

        #endregion

        #region 拷贝对象

        /// <summary>
        /// 服务端拷贝对象
        /// </summary> 
        /// <param name="objType">源文件类型</param>
        /// <param name="objectName">源文件唯一Id</param>
        /// <param name="destType">目标文件类型</param>
        /// <param name="destObjName">目标文件唯一Id</param>
        /// <returns></returns>
        public async Task CopyObjectAsync(StorageObjectTypeDefine objType, string objectName, StorageObjectTypeDefine destType, string destObjName)
        {
            try
            {
                var args = new CopyObjectArgs().WithBucket(await GetBucketName(objType)).WithObject(objectName).WithCopyObjectSource(
               new CopySourceObjectArgs().WithBucket(await GetBucketName(destType)).WithObject(destObjName));
                await _minioClient.CopyObjectAsync(args).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LogHelper.Error($"服务端拷贝对象异常{ex.Message}", ex);
            }

        }
        /// <summary>
        /// 服务端拷贝对象
        /// </summary> 
        /// <param name="bucketName">源存储桶</param>
        /// <param name="objectName">源文件唯一Id</param>
        /// <param name="destBucketName">目标存储桶</param>
        /// <param name="destObjName">目标文件唯一Id</param>
        /// <returns></returns>
        public async Task CopyObjectAsync(string bucketName, string objectName, string destBucketName, string destObjName)
        {
            try
            {
                var args = new CopyObjectArgs().WithBucket(await GetBucketName(bucketName)).WithObject(objectName).WithCopyObjectSource(
                new CopySourceObjectArgs().WithBucket(await GetBucketName(destBucketName)).WithObject(destObjName));
                await _minioClient.CopyObjectAsync(args).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LogHelper.Error($"服务端拷贝对象异常{ex.Message}", ex);
            }

        }
        #endregion

        #region 生成下载url

        /// <summary>
        /// 生成下载url
        /// </summary>
        /// <param name="objType">文件类型</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <param name="expiresSecond">过期时间</param> 
        /// <returns></returns>
        public async Task<string> PresignedGetObjectAsync(StorageObjectTypeDefine objType, string objectName, int expiresSecond = 60)
        {
            try
            {
                if (string.IsNullOrEmpty(objectName))
                {
                    LogHelper.Error("对象名不能为空");
                    return string.Empty;
                }
                var args = new PresignedGetObjectArgs().WithBucket(await GetBucketName(objType)).WithObject(objectName).WithExpiry(expiresSecond);
                return await _minioClient.PresignedGetObjectAsync(args).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LogHelper.Error($"生成下载url异常{ex.Message}", ex);
                return string.Empty;
            }

        }
        /// <summary>
        /// 生成下载url
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <param name="expiresSecond">过期时间</param> 
        /// <returns></returns>
        public async Task<string> PresignedGetObjectAsync(string bucketName, string objectName, int expiresSecond = 60)
        {
            try
            {
                if (string.IsNullOrEmpty(bucketName) || string.IsNullOrEmpty(objectName))
                {
                    LogHelper.Error("对象名不能为空");
                    return string.Empty;
                }
                var args = new PresignedGetObjectArgs().WithBucket(await GetBucketName(bucketName)).WithObject(objectName).WithExpiry(expiresSecond);
                return await _minioClient.PresignedGetObjectAsync(args).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LogHelper.Error($"生成下载url异常{ex.Message}", ex);
                return string.Empty;
            }

        }
        #endregion

        #region 生成上传url

        /// <summary>
        /// 生成上传url
        /// </summary>
        /// <param name="objType">文件类型</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <param name="expiresSecond">过期时间</param> 
        /// <returns></returns>
        public async Task<string> PresignedPutObjectAsync(StorageObjectTypeDefine objType, string objectName, int expiresSecond = 60)
        {
            try
            {
                if (string.IsNullOrEmpty(objectName))
                {
                    LogHelper.Error("对象名不能为空");
                    return string.Empty;
                }
                var args = new PresignedPutObjectArgs().WithBucket(await GetBucketName(objType)).WithObject(objectName).WithExpiry(expiresSecond);
                return await _minioClient.PresignedPutObjectAsync(args).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LogHelper.Error($"生成上传url异常{ex.Message}", ex);
                return string.Empty;
            }
        }
        /// <summary>
        /// 生成上传url
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectName">文件唯一Id</param>
        /// <param name="expiresSecond">过期时间</param> 
        /// <returns></returns>
        public async Task<string> PresignedPutObjectAsync(string bucketName, string objectName, int expiresSecond = 60)
        {
            try
            {
                if (string.IsNullOrEmpty(bucketName) || string.IsNullOrEmpty(objectName))
                {
                    LogHelper.Error("对象名不能为空");
                    return string.Empty;
                }
                var args = new PresignedPutObjectArgs().WithBucket(await GetBucketName(bucketName)).WithObject(objectName).WithExpiry(expiresSecond);
                return await _minioClient.PresignedPutObjectAsync(args).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LogHelper.Error($"生成上传url异常{ex.Message}", ex);
                return string.Empty;
            }
        }
        #endregion

        #region 获取桶名称

        /// <summary>
        /// 获取桶名称(前缀_文件类型)
        /// </summary>
        /// <param name="type">文件类型</param>
        /// <returns></returns>
        private async Task<string> GetBucketName(StorageObjectTypeDefine type)
        {
            //var bucketName = string.Concat(prefix, string.IsNullOrEmpty(prefix) ? "" : "_", type.ToString().ToLower());
            var bucketName = type.ToString().ToLower();
            return await MakeBucketAsync(bucketName);
        }
        /// <summary>
        /// 获取桶名称(自定义)
        /// </summary>
        /// <param name="bucketName">桶名称</param>
        /// <returns></returns>
        private async Task<string> GetBucketName(string bucketName)
        {
            return await MakeBucketAsync(bucketName);
        }
        /// <summary>
        /// 创建存储桶
        /// </summary>
        /// <param name="bucketName">存储桶名称</param>
        /// <returns></returns>
        private async Task<string> MakeBucketAsync(string bucketName)
        {
            var args = new BucketExistsArgs().WithBucket(bucketName);
            if (!await _minioClient.BucketExistsAsync(args).ConfigureAwait(false))
            {
                await _minioClient.MakeBucketAsync(new MakeBucketArgs().WithBucket(bucketName)).ConfigureAwait(false);
                LogHelper.Info($"新建桶：{bucketName}。");
            }
            //设置存储桶公共访问策略
            await SetPublicPolicy(bucketName);
            return bucketName;
        }

        #endregion
        #region 设置存储桶公共访问策略

        /// <summary>
        /// 设置存储桶公共访问策略
        /// </summary>
        private async Task SetPublicPolicy(string bucketName)
        {
            try
            {
                // 设置存储桶公共访问策略
                var publicPolicy = $@"
                {{
                    ""Version"": ""2012-10-17"",
                    ""Statement"": [
                        {{
                            ""Effect"": ""Allow"",
                            ""Principal"": {{ ""AWS"": [""*""] }},
                            ""Action"": [""s3:GetObject""],
                            ""Resource"": [""arn:aws:s3:::{bucketName}/*""]
                        }}
                    ]
                }}";
                var args = new SetPolicyArgs().WithBucket(bucketName).WithPolicy(publicPolicy);
                await _minioClient.SetPolicyAsync(args);
            }
            catch (Exception e)
            {
                LogHelper.Info($"设置存储桶公共访问策略异常：{e.Message}");
            }
        }

        #endregion
        #endregion
    }
}
